﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;

namespace TestPetaPoco.Common
{
    public static class MemberEncrypt
    {
        //密钥
        private const string _secretKey = "sku@bap!i";
        private const string _name = "n:";
        private const string _password = " psw:";

        /// <summary>
        /// 用户加密
        /// </summary>
        /// <param name="userName">账号</param>
        /// <param name="password">密码</param>
        /// <returns>加密数据</returns>
        public static string UserEncrypt(string userName, string password)
        {
            string user = _name + userName + _password + password;
            return UrlHelper.Base64Encrypt(EncryptDESHelper.EncryptDES(user, _secretKey));
        }

        /// <summary>
        /// 用户解密
        /// </summary>
        /// <param name="userEncrypt">key为用户名, value 为密码</param>
        /// <returns>用户名和密码键值对</returns>
        public static KeyValuePair<string, string>? UserDecrypt(string userEncrypt)
        {
            string user = null;
            try
            {
                user = EncryptDESHelper.DecryptDES(UrlHelper.Base64Decrypt(userEncrypt), _secretKey);
            }
            catch (Exception)
            {
                return null;
            }

            int userNameIndex = user.IndexOf(_name);
            int passwordIndex = user.IndexOf(_password);
            if (userNameIndex == 0 && passwordIndex > 0)
            {
                string userName = user.Substring(_name.Length, passwordIndex - _name.Length);
                string password = user.Substring(passwordIndex + _password.Length);
                return new KeyValuePair<string, string>(userName, password);
            }
            return null;
        }

        /// <summary>
        /// 密码加密采用md5方式
        /// </summary>
        /// <param name="password">密码</param>
        /// <returns>加密后的密码</returns>
        public static string EncryptPassWord(string password)
        {
            MD5CryptoServiceProvider provider;
            provider = new MD5CryptoServiceProvider();
            byte[] bytes = Encoding.UTF8.GetBytes(password);
            StringBuilder builder = new StringBuilder();
            bytes = provider.ComputeHash(bytes);
            foreach (byte b in bytes)
                builder.Append(b.ToString("x2").ToLower());
            return builder.ToString();
        }
    }
    public class UrlHelper
    {
        static System.Text.Encoding encoding = System.Text.Encoding.UTF8;

        #region URL的64位编码

        /// <summary>
        /// Url编码
        /// </summary>
        /// <param name="sourthUrl"></param>
        /// <returns></returns>
        public static string Base64Encrypt(string sourthUrl)
        {
            string eurl = HttpUtility.UrlEncode(sourthUrl);
            eurl = Convert.ToBase64String(encoding.GetBytes(eurl));
            return eurl;
        }
        #endregion

        #region URL的64位解码

        /// <summary>
        /// Url解码
        /// </summary>
        /// <param name="eStr"></param>
        /// <returns></returns>
        public static string Base64Decrypt(string value)
        {
            if (!IsBase64(value))
            {
                return value;
            }
            byte[] buffer = Convert.FromBase64String(value);
            string sourthUrl = encoding.GetString(buffer);
            sourthUrl = HttpUtility.UrlDecode(sourthUrl);
            return sourthUrl;
        }
        /// <summary>
        /// 是否是Base64字符串
        /// </summary>
        /// <param name="eStr"></param>
        /// <returns></returns>
        public static bool IsBase64(string eStr)
        {
            if ((eStr.Length % 4) != 0)
            {
                return false;
            }
            if (!Regex.IsMatch(eStr, "^[A-Z0-9/+=]*$", RegexOptions.IgnoreCase))
            {
                return false;
            }
            return true;
        }
        #endregion

        /// <summary>
        /// 参数生成Uri
        /// </summary>
        /// <param name="domain">住域名</param>
        /// <param name="args">参数添加</param>
        /// <returns>Url</returns>
        public static string CreateUrlByParams(string domain, Dictionary<string, object> args)
        {
            string url = string.Empty;
            args.ToList().ForEach(x => url = string.Concat(url, string.Format("&{0}={1}", x.Key, x.Value)));
            return string.Concat(domain, "?", url.Substring(1));
        }


    }
    public static class EncryptDESHelper
    {
        //密钥向量
        private static byte[] Keys = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };

        /// <summary>
        /// DES加密
        /// </summary>
        /// <param name="encryptString">加密字符串</param>
        /// <param name="secretKey">密钥</param>
        /// <returns>加密结果</returns>
        public static string EncryptDES(string encryptString, string secretKey)
        {
            byte[] rgbKey = ProcessEncryptKey(secretKey);
            byte[] rgbIV = Keys;
            byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString);
            DESCryptoServiceProvider dCSP = new DESCryptoServiceProvider();
            MemoryStream mStream = new MemoryStream(); CryptoStream cStream = new CryptoStream(mStream, dCSP.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
            cStream.Write(inputByteArray, 0, inputByteArray.Length); cStream.FlushFinalBlock();
            return Convert.ToBase64String(mStream.ToArray());
        }

        /// <summary>
        /// DES解密
        /// </summary>
        /// <param name="decryptString">解密字符串</param>
        /// <param name="secretKey">密钥</param>
        /// <returns>解密结果</returns>
        public static string DecryptDES(string decryptString, string secretKey)
        {
            byte[] rgbKey = ProcessEncryptKey(secretKey);
            byte[] rgbIV = Keys;
            byte[] inputByteArray = Convert.FromBase64String(decryptString);
            DESCryptoServiceProvider DCSP = new DESCryptoServiceProvider();
            MemoryStream mStream = new MemoryStream();
            CryptoStream cStream = new CryptoStream(mStream, DCSP.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
            cStream.Write(inputByteArray, 0, inputByteArray.Length);
            cStream.FlushFinalBlock();
            return Encoding.UTF8.GetString(mStream.ToArray());
        }

        //处理密钥
        private static byte[] ProcessEncryptKey(string secretKey)
        {
            if (secretKey.Length > 8)
            {
                secretKey = secretKey.Substring(0, 8);
            }
            else if (secretKey.Length < 8)
            {
                secretKey = secretKey + "se!er@cu".Substring(0, 8 - secretKey.Length);
            }
            return Encoding.UTF8.GetBytes(secretKey);
        }

    }
}